package com.feinno.urcs.group.http.servlet;

import com.feinno.urcs.group.http.handler.*;
import com.feinno.urcs.group.http.util.StringHelper;
import com.feinno.urcs.group.http.util.XcapParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by wuzhiguo on 15-5-12.
 */
public class GroupHttpDispatcher {

    private static final Logger LOGGER = LoggerFactory.getLogger(GroupHttpDispatcher.class);

    // HTTP Methods
    private static final String HTTP_METHOD_GET = "GET";
    private static final String HTTP_METHOD_PUT = "PUT";
    private static final String HTTP_METHOD_DELETE = "DELETE";

    // Document Selector Items
    private static final String GROUP_AUID = "public-group";
    private static final String GROUP_ZONE = "global";
    private static final String GROUP_FILENAME = "index.xml";
    private static final String GROUP_LIST_AUID = "public-group";
    private static final String GROUP_LIST_ZONE = "users";
    private static final String GROUP_LIST_FILENAME = "index.xml";

    // GET
    private static final BaseHttpServlet getGroupListHandler = new GetGroupListHandler();
    private static final BaseHttpServlet getGroupInfoHandler = new GetGroupInfoHandler();
    // PUT
    private static final BaseHttpServlet createGroupHandler = new CreateGroupHandler();
    private static final BaseHttpServlet groupInviteHandler = new GroupInviteHandler();
    private static final BaseHttpServlet groupInviteReplyHandler = new GroupInviteReplyHandler();
    // PUT
    private static final BaseHttpServlet updateGroupNameHandler = new UpdateGroupNameHandler();
    private static final BaseHttpServlet updateGroupMemberNameHandler = new UpdateGroupMemberNameHandler();
    private static final BaseHttpServlet changeGroupOwnerHandler = new ChangeGroupOwnerHandler();
    // DELETE
    private static final BaseHttpServlet deleteGroupHandler = new DeleteGroupHandler();
    private static final BaseHttpServlet removeGroupMemberHandler = new RemoveGroupMemberHandler();

    public static BaseHttpServlet dispatch(String method, XcapParser parser) {
        BaseHttpServlet handler = null;
        try {
            switch (method) {
                case HTTP_METHOD_GET:
                    if (parser.getAuid().equals(GROUP_LIST_AUID)
                            && parser.getZone().equals(GROUP_LIST_ZONE)
                            && parser.getFilename().equals(GROUP_LIST_FILENAME)
                            && (StringHelper.isNullOrEmpty(parser.getNodeSelector()))) {
                        // GET /public-group/users/sip:alice@feinno.com/index.xml HTTP/1.1
                        handler = getGroupListHandler;
                    } else if (parser.getAuid().equals(GROUP_AUID)
                            && parser.getZone().equals(GROUP_ZONE)
                            && parser.getFilename().equals(GROUP_FILENAME)
                            && (StringHelper.isNullOrEmpty(parser.getNodeSelector()))) {
                        // GET /public-group/global/sip:my_group@feinno.com/index.xml HTTP/1.1
                        handler = getGroupInfoHandler;
                    }
                    break;
                case HTTP_METHOD_PUT:
                    if (parser.getAuid().equals(GROUP_AUID)
                            && parser.getZone().equals(GROUP_ZONE)
                            && parser.getFilename().equals(GROUP_FILENAME)) {
                        if (StringHelper.isNullOrEmpty(parser.getNodeSelector())) {
                            // PUT /public-group/global/sip:my_group@feinno.com/index.xml HTTP/1.1
                            handler = createGroupHandler;
                        } else if (parser.getNodeSelectorArray() != null
                                && parser.getNodeSelectorArray().length == 4
                                && parser.getNodeSelectorArray()[0].isEmpty()
                                && parser.getNodeSelectorArray()[1].equals("public-group")
                                && parser.getNodeSelectorArray()[2].equals("list")
                                && parser.getNodeSelectorArray()[3].startsWith("entry")) {
                            // PUT /public-group/global/sip:my_group@feinno.com/index.xml/~~/public-group/list/entry[@uri='sip:bob@feinno.com'] HTTP/1.1
                            handler = groupInviteHandler;
                        } else if (parser.getNodeSelectorArray() != null
                                && parser.getNodeSelectorArray().length == 5
                                && parser.getNodeSelectorArray()[0].isEmpty()
                                && parser.getNodeSelectorArray()[1].equals("public-group")
                                && parser.getNodeSelectorArray()[2].equals("list")
                                && parser.getNodeSelectorArray()[3].startsWith("entry[")
                                && parser.getNodeSelectorArray()[4].equals("@status")) {
                            // PUT /public-group/global/sip:my_group@feinno.com/index.xml/~~/public-group/list/entry[@uri='sip:bob@feinno.com']/@status HTTP/1.1
                            handler = groupInviteReplyHandler;
                        } else if (parser.getNodeSelectorArray() != null
                                && parser.getNodeSelectorArray().length == 4
                                && parser.getNodeSelectorArray()[0].isEmpty()
                                && parser.getNodeSelectorArray()[1].equals("public-group")
                                && parser.getNodeSelectorArray()[2].equals("list")
                                && parser.getNodeSelectorArray()[3].equals("@name")) {
                            // PUT /public-group/global/sip:my_group@feinno.com/index.xml/~~/public-group/list/@name HTTP/1.1
                            handler = updateGroupNameHandler;
                        } else if (parser.getNodeSelectorArray() != null
                                && parser.getNodeSelectorArray().length == 5
                                && parser.getNodeSelectorArray()[0].isEmpty()
                                && parser.getNodeSelectorArray()[1].equals("public-group")
                                && parser.getNodeSelectorArray()[2].equals("list")
                                && parser.getNodeSelectorArray()[3].startsWith("entry[")
                                && parser.getNodeSelectorArray()[4].equals("display-name")) {
                            // PUT /public-group/global/sip:my_group@feinno.com/index.xml/~~/public-group/list/entry[@uri='sip:bob@feinno.com']/display-name HTTP/1.1
                            handler = updateGroupMemberNameHandler;
                        } else if (parser.getNodeSelectorArray() != null
                                && parser.getNodeSelectorArray().length == 5
                                && parser.getNodeSelectorArray()[0].isEmpty()
                                && parser.getNodeSelectorArray()[1].equals("public-group")
                                && parser.getNodeSelectorArray()[2].equals("list")
                                && parser.getNodeSelectorArray()[3].startsWith("entry[")
                                && parser.getNodeSelectorArray()[4].equals("@owner")) {
                            // PUT /public-group/global/sip:my_group@feinno.com/index.xml/~~/public-group/list/entry[@uri='sip:bob@feinno.com']/@owner HTTP/1.1
                            handler = changeGroupOwnerHandler;
                        }
                    }
                    break;
                case HTTP_METHOD_DELETE:
                    if (parser.getAuid().equals(GROUP_AUID)
                            && parser.getZone().equals(GROUP_ZONE)
                            && parser.getFilename().equals(GROUP_FILENAME)) {
                        if (StringHelper.isNullOrEmpty(parser.getNodeSelector())) {
                            // DELETE /public-group/global/sip:my_group@feinno.com/index.xml HTTP/1.1
                            handler = deleteGroupHandler;
                        } else if (parser.getNodeSelectorArray() != null
                                && parser.getNodeSelectorArray().length == 4
                                && parser.getNodeSelectorArray()[0].isEmpty()
                                && parser.getNodeSelectorArray()[1].equals("public-group")
                                && parser.getNodeSelectorArray()[2].equals("list")
                                && parser.getNodeSelectorArray()[3].startsWith("entry[")) {
                            // DELETE /public-group/global/sip:my_group@feinno.com/index.xml/~~/public-group/list/entry[@uri='sip:bob@feinno.com'] HTTP/1.1
                            handler = removeGroupMemberHandler;
                        }
                    }
                    break;
                default:
                    break;
            }

        } catch (Exception ex) {
            LOGGER.error(String.format("dispatch() Error. method: %s parser: %s", method, parser), ex);
        }

        return handler;
    }

}
